#
# Ph::FastDB
#
module Ph

	#
	# Migration Class
	#
	#	Handles migration tasks. 
	#
	class Migration

		Version = Ph::VERSION

		def initialize(connection, *default_elements)
			@connection = connection
			@elements   = Hash.new

			default_elements.each do |k|
				@elements[k.name.to_sym] = k
			end

			@element = @elements
		end
		
		#
		# Creates the Element e. If @recursive is true it will also create its children.
		#
		def create(e)

			e.each do |name, k|
				puts "Creating #{k.class}: #{k.name}" if @verbose
				@connection.create(k) rescue puts "Element #{k.class}:#{k.name} skipped (#{$!})."
				if (k.respond_to?(:elements) && @recursive) then
					self.create(k.elements) 
				end

			end

		end

		def drop(e)

			e.each do |name, k|
				# Drop Children if Recursive
				self.drop(k.elements) if (@recursive && k.respond_to?(:elements))

				puts "Dropping #{k.class}: #{k.name}" if @verbose
				@connection.drop(k) rescue puts "Element #{k.class}:#{k.name} failed (#{$!})."
			end

		end

		def reset
			self.drop(@element)
			self.create(@element)
		end

		def list(what, container='')
			what.each do |k, v| 
				puts "#{container}:#{k} (#{v.class})"
				self.list(v.elements, k) if v.respond_to?(:elements)
			end
		end

		def verbose
			@verbose = true
			puts "Ph::Migration #{Version}"
		end

		def recursive
			@recursive = true
			puts "Recursive Mode: ON" if @verbose
		end

		def select(element)
			map = element.split(':')
			els = @elements

			map.each do |k|
				els = els[k.to_sym]
			end

			puts "#{els.name} Selected." if @verbose
		
			@element = {els.name.to_sym => els}
		end

		#
		#
		def run 

			require 'optparse'

			OptionParser.new do |opts|
				opts.banner = "Usage: #{$0} task option"

				opts.separator "Tasks"
				opts.on('--create', "Creates element.") { self.create(@element) }
				opts.on('--drop', "Drops element.") { self.drop(@element) }
				opts.on('--reset', "Drops then Creates element.") { self.reset }
				opts.on('--list', "Lists available resources.") { self.list(@element) }

				opts.separator "Options:"
				opts.on('-r', '--recursive', "Recursive Mode") { self.recursive }
				opts.on('-v', '--version', "Prints version.") { puts Ph::VERSION_STRING; exit }
				opts.on('--verbose', 'Verbose mode') { self.verbose }
				opts.on('-e', '--element ELEMENT', "Selects element(Schema, Table, Query, etc)") { |el| self.select(el) }

				opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }

				puts opts if ARGV.length == 0

			end.parse!

			@connection.close # Opened at Constructor.
		end

	end

end
